﻿using aier.dataaccess.dapper;
using aier.dataaccess.model;
using aier.xrm.wcf;
using log4net;
using Microsoft.Xrm.Sdk;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace aier.business.logic
{
    public class ScreenBll
    {
        public ILog log { get; set; }
        public ResResult resResult { get; set; }
        public ScreenDal screenDal { get; set; }
        public ScreenTSCItemDal screenTSCItemDal { get; set; }
        public EquipmentDal equipmentDal { get; set; }
        public CommonWcf commonWcf { get; set; }

        #region 查询
        public IEnumerable<EquipmentView> QueryAllEquipment()
        {
            return equipmentDal.GetAllEquipments().Select(t=>new EquipmentView() {
                id = t.new_number,
                name = t.new_name
            });
        }


        /// <summary>
        /// 根据id查询筛查信息
        /// </summary>
        /// <param name="screenId">筛查信息id</param>
        /// <returns>单条筛查信息</returns>
        public ScreenView FetchScreenByScreenID(Guid screenId) {
            ScreenView screenView = screenDal.FetchScreenByScreenID(screenId);
            screenView.equipList = equipmentDal.GetEquipmentsByScreenId(screenId).ToList();
            screenView.equipListstr = String.Join(", ", screenView.equipList.Select(x => x.new_name).ToArray());
            //String.Join(", ", names.ToArray())
            return screenView;
        }

        /// <summary>
        /// 根据id查询筛查信息与设备资源
        /// 原程序 ：ScreeningServiceImpl-> ScreenInfo4WS qryScreenInfo(String screenid, DoctorUser doctorUser)
        /// </summary>
        /// <param name="screenId">筛查信息id</param>
        /// <returns>单条筛查信息</returns>
        public ScreenView QueryScreenViewByScreenID(Guid screenId)
        {
            ScreenView screenView = screenDal.FetchScreenByScreenID(screenId);
            screenView.equipList = equipmentDal.GetEquipmentsByScreenId(screenId).ToList();
            screenView.equipmentNames = string.Join(",", screenView.equipList.Select(g => g.new_name));
            screenView.equipmentIds =string.Join(",", screenView.equipList.Select(g=>g.new_equipmentId.ToString()));
            return screenView;
        }

        /// <summary>
        /// 获取所有筛查活动
        /// 原程序方法 ：ScreeningServiceImpl-> findAllScInfos   
        /// </summary>
        /// <param name="pageIndex">当前页索引</param>
        /// <param name="pageSize">页面显示条数</param>
        /// <returns></returns>
        public IEnumerable<ScreenView> GetAllScreen(int pageIndex, int pageSize)
        {
            return screenDal.GetAllScreen(pageIndex, pageSize);
        }

        /// <summary>
        /// 查询当前用户相关的筛查排期列表,负责人或组员里包含登录用户
        /// 原程序方法：ScreeningServiceImpl-> findScpqByUsername(String username)
        /// <param name="domainname">域账号</param>
        /// <returns></returns>
        public IEnumerable<Screen_PQView> GetScreenByDomainName(string domainname)
        {
            return screenDal.GetScreenByDomainName(domainname);
        }

        /// <summary>
        /// 分页查询当前用户相关的筛查排期列表,负责人或组员里包含登录用户
        /// 原程序方法：ScreeningServiceImpl->findScpqByUsername(String username, int fromIndex, int toIndex)
        /// <param name="domainname">域账号</param>
        /// <param name="pageIndex">当前页索引</param>
        /// <param name="pageSize">页面显示条数</param>
        /// <returns></returns>
        public PageResult<Screen_PQView> GetScreenByDomainName(string domainname, int pageIndex, int pageSize)
        {
            //计算开始与结束位置
            int tmpPageSize = pageSize + 1;
            

            PageResult<Screen_PQView> pageResult = new PageResult<Screen_PQView>();
            Stopwatch stopwatch = new Stopwatch();
            stopwatch.Start();
            IEnumerable<Screen_PQView> views = screenDal.GetScreenByDomainName(domainname, pageIndex, tmpPageSize).OrderByDescending(t=>t.new_startdate.Value);
            stopwatch.Stop();
            log.Info($"---GetScreenByDomainName---{stopwatch.Elapsed.TotalSeconds}");
            pageResult.datas = views.Skip(0).Take(pageSize);
            pageResult.existsnextdata = views.Count() > pageSize;
            stopwatch.Reset();
            stopwatch.Start();
            pageResult.total = screenDal.GetCountScreenByDomainName(domainname);
            stopwatch.Stop();
            log.Info($"---GetCountScreenByDomainName---{stopwatch.Elapsed.TotalSeconds}");

            return pageResult;
        }
        public PageResult<Screen_PQView> GetScreenByDomainName1(string domainname, int pageIndex, int pageSize)
        {
            //计算开始与结束位置
            int tmpPageSize = pageSize + 1;


            PageResult<Screen_PQView> pageResult = new PageResult<Screen_PQView>();
            Stopwatch stopwatch = new Stopwatch();
            stopwatch.Start();
            IEnumerable<Screen_PQView> views = screenDal.GetScreenByDomainName1(domainname, pageIndex, tmpPageSize).OrderByDescending(t => t.new_startdate.Value);
            stopwatch.Stop();
            log.Info($"---GetScreenByDomainName---{stopwatch.Elapsed.TotalSeconds}");
            pageResult.datas = views.Skip(0).Take(pageSize);
            pageResult.existsnextdata = views.Count() > pageSize;
            stopwatch.Reset();
            stopwatch.Start();
            pageResult.total = screenDal.GetCountScreenByDomainName1(domainname);
            stopwatch.Stop();
            log.Info($"---GetCountScreenByDomainName---{stopwatch.Elapsed.TotalSeconds}");

            return pageResult;
        }

        /// <summary>
        /// 分页查询当前用户相关的筛查排期列表(不包括大客户和大学校园筛查)
        /// 原程序方法：ScreeningServiceImpl-> findScpqNoBigByUsername(String username, int fromIndex, int toIndex)
        /// </summary>
        /// <param name="domainname">域账号</param>
        /// <param name="pageIndex">当前页索引</param>
        /// <param name="pageSize">页面显示条数</param>
        /// <returns></returns>
        public PageResult<Screen_PQView> GetScreenNoBigDomainName(string domainname, int pageIndex, int pageSize)
        {
            //计算开始与结束位置
            int tmpPageSize = pageSize + 1;

            PageResult<Screen_PQView> pageResult = new PageResult<Screen_PQView>();
            IEnumerable<Screen_PQView> views = screenDal.GetScreenNoBigDomainName(domainname, pageIndex, tmpPageSize);
            pageResult.datas = views.Skip(0).Take(pageSize);
            pageResult.existsnextdata = views.Count() > pageSize;
            pageResult.total = screenDal.GetCountScreenNoBigDomainName(domainname);

            return pageResult;
        }

        /// <summary>
        /// 查询当前用户相关的筛查排期列表,负责人或组员里包含登录用户
        /// 原程序方法：ScreeningServiceImpl-> findScpqByUsername(String username, String scState) 
        /// </summary>
        /// <param name="domainname">域账号</param>
        /// <param name="scState">筛查状态</param>
        /// <returns></returns>
        public IEnumerable<Screen_PQView> GetScreenByDomainNameAndState(string domainname, string scState)
        {
            return screenDal.GetScreenByDomainNameAndState( domainname,  scState);
        }

        /// <summary>
        /// 分页查询当前用户相关的筛查排期列表,负责人或组员里包含登录用户
        /// 原程序方法：ScreeningServiceImpl-> findScpqByUsername(String username, String scState, int fromIndex, int toIndex)
        /// </summary>
        /// <param name="domainname">域账号</param>
        /// <param name="scState">筛查状态</param>
        /// <param name="pageIndex">当前页索引</param>
        /// <param name="pageSize">页面大小</param>
        /// <returns></returns>
        public PageResult<Screen_PQView> GetScreenByDomainNameAndState(string domainname, string scState, int pageIndex, int pageSize)
        {
            //计算开始与结束位置
            int tmpPageSize = pageSize + 1;

            PageResult<Screen_PQView> pageResult = new PageResult<Screen_PQView>();
            IEnumerable<Screen_PQView> views = screenDal.GetScreenByDomainNameAndState(domainname, scState, pageIndex, tmpPageSize);
        
            pageResult.datas = views.Skip(0).Take(pageSize);
            pageResult.existsnextdata = views.Count() > pageSize;
            pageResult.total = screenDal.GetCountScreenByDomainNameAndState(domainname, scState);

            return pageResult;
        }
        public PageResult<Screen_PQView> GetScreenByDomainNameAndState1(string domainname, string scState, int pageIndex, int pageSize)
        {
            //计算开始与结束位置
            int tmpPageSize = pageSize + 1;

            PageResult<Screen_PQView> pageResult = new PageResult<Screen_PQView>();
            IEnumerable<Screen_PQView> views = screenDal.GetScreenByDomainNameAndState1(domainname, scState, pageIndex, tmpPageSize);

            pageResult.datas = views.Skip(0).Take(pageSize);
            pageResult.existsnextdata = views.Count() > pageSize;
            pageResult.total = screenDal.GetCountScreenByDomainNameAndState1(domainname, scState);

            return pageResult;
        }

        /// <summary>
        /// 分页查询当前用户相关的筛查排期列表(不包括大客户和大学校园筛查)
        /// 原程序方法：ScreeningServiceImpl-> findScpqNoBigByUsername(String username, String scState, int fromIndex, int toIndex)
        /// </summary>
        /// <param name="domainname">域账号</param>
        /// <param name="scState">筛查状态</param>
        /// <param name="pageIndex">当前页索引</param>
        /// <param name="pageSize">页面大小</param>
        /// <returns></returns>
        public PageResult<Screen_PQView> GetScreenNoBigDomainNameAndState(string domainname, string scState, int pageIndex, int pageSize)
        {
            //计算开始与结束位置
            int tmpPageSize = pageSize + 1;

            PageResult<Screen_PQView> pageResult = new PageResult<Screen_PQView>();
            IEnumerable<Screen_PQView> views = screenDal.GetScreenNoBigDomainNameAndState(domainname, scState, pageIndex, pageSize) ;
            pageResult.datas = views.Skip(0).Take(pageSize);
            pageResult.existsnextdata = views.Count() > pageSize;
            pageResult.total = screenDal.GetCountScreenNoBigDomainNameAndState(domainname, scState);

            return pageResult;
        }

        /// <summary>
        /// 根据客户ID查询该客户所有参与的筛查信息
        /// 原程序方法：ScreeningServiceImpl-> findScInfosByCustomerId(String customerId)  ,findScInfosByLeadId(String leadId)
        /// </summary>
        /// <param name="customerid">客户ID</param>
        /// <returns></returns>
        public IEnumerable<Screen_Info_For_AccountView> GetScreenByCustomerId(Guid customerid)
        {
            return screenDal.GetScreenByCustomerId(customerid);
        }

        /// <summary>
        /// 根据姓名,电话，身份证模糊查询CRM客户信息
        /// 原程序方法：ScreeningServiceImpl-> selectAierAccountCustomerinfos(DoctorUser user, String key)
        /// </summary>
        /// <param name="userInfo">用户信息</param>
        /// <param name="fullname">姓名或电话或身份证,如果是姓名模糊查询有可能会很多记录，所以需要分页查询</param>
        /// <returns></returns>
        public PageResult<Account_CustomerInfoView> GetAccountCustomerInfoByCondition(UserInfo userInfo, string condition, int pageIndex, int pageSize)
        {
            //计算开始与结束位置
            int tmpPageSize = pageSize + 1;
            IEnumerable<Account_CustomerInfoView> customerInfos = null;
            PageResult<Account_CustomerInfoView> pageResult = new PageResult<Account_CustomerInfoView>();

            if (CommonUtil.IsMobile(condition))
            {
                //如果为手机
                customerInfos = screenDal.GetAccountCustomerInfoByPhone(userInfo, condition);
                pageResult.existsnextdata = false;
                pageResult.datas = customerInfos;
                pageResult.total = customerInfos.Count();
            }
            else if (CommonUtil.IsIDCard(condition))
            {
                //如果为身份证
                customerInfos = screenDal.GetAccountCustomerInfoByCitizenid(userInfo, condition);
                pageResult.existsnextdata = false;
                pageResult.datas = customerInfos;
                pageResult.total = customerInfos.Count();
            }
            else
            {
                //否则为姓名,姓名模糊查询有可能会很多记录，所以需要分页查询
                customerInfos = screenDal.GetAccountCustomerInfoByFullName(userInfo, condition,  pageIndex, tmpPageSize);
                pageResult.datas = customerInfos.Skip(0).Take(pageSize);
                pageResult.existsnextdata = customerInfos.Count() > pageSize;
                pageResult.total = screenDal.GetCountAccountCustomerInfoByFullName(userInfo, condition);
            }

            return pageResult;
        }


        /// <summary>
        /// 统计页面查询客户列表 姓名或手机或身份证模糊查询
        /// 原程序方法：ScreeningServiceImpl-> statistics4CustomerList(String teamid, String startdate, String enddate, String qryType, String key) 
        /// </summary>
        /// <param name="teamid">筛查组ID</param>
        /// <param name="startdate">预约创建日期</param>
        /// <param name="enddate">预约创建日期</param>
        /// <param name="qryType">查询类型："tohospital"（到院）,"sign"（签约手术）,"operate"（手术）,"notoperate"（非手术）</param>
        /// <param name="fullname">姓名或手机或身份证模糊查询</param>
        /// <returns></returns>
        public IEnumerable<Account_CustomerInfoView> GetAccountCustomerInfoByTeamIdAndCreatedOnAndCondition(string teamid, string startdate, string enddate, string qryType, string condition)
        {
            IEnumerable<Account_CustomerInfoView> customerInfos = null;

            if (CommonUtil.IsMobile(condition))
            {
                //如果为手机
                customerInfos = screenDal.GetAccountCustomerInfoByTeamIdAndCreatedOnAndPhone( teamid,  startdate,  enddate,  qryType, condition);
            }
            else if (CommonUtil.IsIDCard(condition))
            {
                //如果为身份证
                customerInfos = screenDal.GetAccountCustomerInfoByTeamIdAndCreatedOnAndCitizenid(teamid, startdate, enddate, qryType, condition);
            }
            else
            {
                //否则为姓名
                customerInfos = screenDal.GetAccountCustomerInfoByTeamIdAndCreatedOnAndFullname(teamid, startdate, enddate, qryType, condition);
            }

            return customerInfos;
        }

        /// <summary>
        /// 根据客户id查询CRM单个客户信息
        /// 原程序方法：ScreeningServiceImpl-> selectAierAccountCustomerinfoByLeadId(String leadid) 
        /// </summary>
        /// <param name="leadid">客户id</param>
        /// <returns></returns>
        public Account_CustomerInfoView GetAccountCustomerInfoByLeadId(Guid leadid)
        {
           return screenDal.GetAccountCustomerInfoByLeadId(leadid);
        }

        /// <summary>
        /// 根据客户id查询CRM单个客户信息
        /// 原程序方法：ScreeningServiceImpl-> queryCustomerInfoByTaskid(String taskid)
        /// </summary>
        /// <param name="taskid">客户id</param>
        /// <returns></returns>
        public Account_CustomerInfoView GetAccountCustomerInfoByTaskId(Guid taskid)
        {
            return screenDal.GetAccountCustomerInfoByTaskId( taskid);
        }

        /// <summary>
        ///  查询大客户活动合作项目
        ///  原程序 ScreeningServiceImpl-> findJointProjectInfo(int projectCategory, int projectPhase)
        /// </summary>
        /// <param name="projectCategory">项目类别</param>
        /// <param name="projectPhase">项目状态</param>
        public IEnumerable<JoinprojectView> QueryJoinProjectByCategoryAndPhase(int projectCategory, int projectPhase)
        {
            return screenDal.QueryJoinProjectByCategoryAndPhase( projectCategory,  projectPhase);
        }

        /// <summary>
        /// 查询筛查检查项目模板
        /// 原程序：ScreeningServiceImpl-> listNewTScPageElement(String name, String ownerid, Integer statecode)
        /// </summary>
        /// <param name="name">名称</param>
        /// <param name="ownerid">负责人ID</param>
        /// <param name="statecode">状态</param>
        /// <returns></returns>
        public IEnumerable<T_SC_Page_ElementView> QueryPageElementByNameAndOwnerIdAndStateCode(string name, string ownerid, int statecode)
        {
            return screenDal.QueryPageElementByNameAndOwnerIdAndStateCode(name,ownerid,statecode);
        }

        /// <summary>
        /// 营销资源设备查询
        /// 原程序：ScreeningServiceImpl-> listEquipment(String name, Integer type, Integer statecode)
        /// </summary>
        /// <param name="name">名称</param>
        /// <param name="type">资源分类</param>
        /// <param name="statecode">状态</param>
        /// <returns></returns>
        public IEnumerable<EquipmentView> QueryEquipmentViewByNameAndType(string name, int type, int statecode)
        {
            return equipmentDal.QueryEquipmentViewByNameAndType(name,type,statecode);
        }

        /// <summary>
        /// 营销资源设备查询 根据设备ID查询，id间用','号分开
        /// 原程序：ScreenInfoServiceImpl-> qryNewEquipmentsByEqids(String eqids)
        /// </summary>
        /// <param name="eqids">id间用','号分开</param>
        /// <returns></returns>
        public IEnumerable<EquipmentView> QueryEquipmentViewById(string eqids)
        {
            return equipmentDal.QueryEquipmentViewById(eqids);
        }

        /// <summary>
        /// 营销资源设备名称查询 根据设备ID查询，id间用','号分开
        /// 原程序：ScreenInfoServiceImpl-> qryEqNamesByEqids(String eqids)
        /// </summary>
        /// <param name="eqids">id间用','号分开</param>
        /// <returns></returns>
        public string QueryEquipmentName(string eqids)
        {
            IEnumerable<EquipmentView> views = equipmentDal.QueryEquipmentViewById(eqids);

            return (views != null && views.Count() > 0) ? string.Join(",", views.Select(g => g.new_name).ToArray()) : string.Empty;
        }

        /// <summary>
        /// 根据筛查ID,查询营销资源设备
        /// 原程序 ：ScreenInfoServiceImpl-> qryEquipmentIdsByScreenid(String screenid, DoctorUser doctorUser)
        /// </summary>
        /// <param name="screenId">筛查ID</param>
        /// <returns></returns>
        public string QueryEquipmentIdsByScreenId(string screenId)
        {
            IEnumerable<ScreenEquipmentView> equipmentViews = equipmentDal.QueryScreenEquipmentViewByScreenId(screenId);

            return  (equipmentViews != null && equipmentViews.Count() > 0)? string.Join(",", equipmentViews.Select(g=>g.new_equipmentid).ToArray()) : string.Empty;
        }

        /// <summary>
        /// 获取所有筛查检查项目
        /// 原程序 ：ScItemServiceImpl-> Map<String, AierTScItem> getAll()
        /// </summary>
        /// <returns></returns>
        public IEnumerable<T_SC_ItemView> GetScreenAllSCItem()
        {
            return screenTSCItemDal.GetScreenAllSCItem();
        }

        /// <summary>
        /// 根据ItemId获取筛查检查项目
        /// 原程序 ：ScItemServiceImpl-> AierTScItem getById(String itemid)
        /// </summary>
        /// <returns></returns>
        public T_SC_ItemView GetScreenSCItemByItemId(string itemId)
        {
            return screenTSCItemDal.GetScreenSCItemByItemId(itemId);
        }

        /// <summary>
        /// 根据leadId获取筛查活动中的筛查项目
        /// </summary>
        /// <param name="leadId"></param>
        /// <returns></returns>
        public IEnumerable<dynamic> GetScreenItemData(Guid leadId)
        {
            if(leadId != Guid.Empty)
            {
                IEnumerable<dynamic> scrrenItemData= screenDal.GetScreenItemData(leadId);
                return scrrenItemData;
            }
            return null;
        }

        #endregion

        #region Update 更新
        /// <summary>
        /// 批量更新筛查活动public Result updateScResult(DoctorUser user, List<TScResult> list)
        /// </summary>
        /// <param name="screens"></param>
        /// <returns></returns>
        public List<ResResult> UpdateScreenBatch(List<Screen> screens)
        {
            List<ResResult> resResults = new List<ResResult>();
            if (screens == null || screens.Count() != 0)
            {
                resResults.Add(resResult.FailResult("ScreenBll-> CreateScreen: 传入列表为空"));
                return resResults;
            }
            foreach (Screen item in screens)
            {
                resResults.Add(UpdateScreen(item));
            }
            return resResults;
        }


        /// <summary>
        /// 批量创建筛查活动public Result saveScResult(DoctorUser user, List<TScResult> list)
        /// </summary>
        /// <param name="screen">筛查活动对像</param>
        /// <returns></returns>
        public List<ResResult> CreateScreenBatch(List<Screen>  screens) {
            List < ResResult >  resResults = new List<ResResult>();
            if (screens==null||screens.Count()!=0) {
                resResults.Add(resResult.FailResult("ScreenBll-> CreateScreen: 传入列表为空"));
                return resResults;
            }
            foreach (Screen item in screens) {
                resResults.Add(CreateScreen(item));
            }
            return resResults;
        }

        /// <summary>
        /// 创建筛查活动
        /// </summary>
        /// <param name="screen">筛查活动对像</param>
        /// <returns></returns>
        public ResResult CreateScreen(Screen screen)
        {
            Guid entityId = Guid.Empty;
            Entity entity = screen.AsCrmEntity();

            try
            {
                if (Guid.Empty.Equals(screen.userid))
                {
                    entityId = commonWcf.CreateEntity(entity);
                }
                else
                {
                    entityId = commonWcf.CreateEntityProxy(screen.userid, entity);
                }


                return resResult.SuccessResult(entityId);
            }
            catch (Exception ex)
            {
                log.Error("ScreenBll-> CreateScreen: " + ex.Message);
                return resResult.FailResult(ex.Message);
            }
        }



        /// <summary>
        /// 更新筛查活动
        /// 原程序 ：ScreeningServiceImpl-> scPersonCheckIn(ScCheckInfo scCheckInfo) 状态为进行中
        ///          ScreeningServiceImpl-> UpdateCheckItem(DoctorUser user, String scid, int new_templatetype)根据SCID更新筛查模板
        /// </summary>
        /// <param name="screen">筛查活动对像</param>
        /// <returns></returns>
        public ResResult UpdateScreen(Screen screen)
        {
            try
            {
                Entity entity = screen.AsCrmEntity();
                List<string> removeEntityAttr = new List<string>();
                RemoveNullAttr(screen, entity, removeEntityAttr);

                if (Guid.Empty.Equals(screen.userid))
                {
                    commonWcf.UpdateEntityById(entity);
                }
                else
                {
                    commonWcf.UpdateEntityProxyById(screen.userid, entity);
                }

                return resResult.SuccessResult();
            }
            catch (Exception ex)
            {
                log.Error("ScreenBll-> UpdateScreen: " + ex.Message);
                return resResult.FailResult(ex.Message);
            }
        }

        private  void RemoveNullAttr(Screen screen, Entity entity, List<string> removeEntityAttr)
        {
            if (string.IsNullOrWhiteSpace(screen.new_outreach))
            {
                removeEntityAttr.Add("new_outreach");
            }
            if (string.IsNullOrWhiteSpace(screen.new_preach))
            {
                removeEntityAttr.Add("new_preach");
            }
            if (string.IsNullOrWhiteSpace(screen.new_thedriver))
            {
                removeEntityAttr.Add("new_thedriver");
            }
            if (string.IsNullOrWhiteSpace(screen.new_screeningdoctor))
            {
                removeEntityAttr.Add("new_screeningdoctor");
            }
            if (string.IsNullOrWhiteSpace(screen.new_screeningnurse))
            {
                removeEntityAttr.Add("new_screeningnurse");
            }
            if (string.IsNullOrWhiteSpace(screen.new_other))
            {
                removeEntityAttr.Add("new_other");
            }

            CommonUtil.RetainEntityAttributes(entity, removeEntityAttr.ToArray());
        }

        /// <summary>
        /// 按筛查组获取筛统计信息
        /// </summary>
        /// <param name="screenteamid">筛查组ID</param>
        /// <param name="startDate">开始时间</param>
        /// <param name="endDate">结果时间</param>
        /// <returns></returns>
        public ScreenStatisticsView QryScreenStatisticsBy(Guid screenteamid, string startDate, string endDate)
        {
            return screenDal.QryScreenStatisticsBy(screenteamid, startDate, endDate);
        }

        #endregion

    }
}
